package com.ferryc.tcc.impl;

import com.ferryc.entity.Order;
import com.ferryc.entity.OrderDetail;
import com.ferryc.entity.Products;
import com.ferryc.entity.Stroage;
import com.ferryc.exception.BaseException;
import com.ferryc.exception.HandleException;
import com.ferryc.exception.NSFException;
import com.ferryc.exception.UnderstockException;
import com.ferryc.fegin.PayFeignClient;
import com.ferryc.fegin.StroageFeignClient;
import com.ferryc.mapper.IOrderMapper;
import com.ferryc.mapper.OrderDetailMapper;
import com.ferryc.model.Product;
import com.ferryc.model.Result;
import com.ferryc.service.IProductsService;
import com.ferryc.tcc.IOrderTccService;
import com.ferryc.tccfegin.PayTccFeignClient;
import com.ferryc.tccfegin.StroageTccFeignClient;
import com.ferryc.utils.DigitalUtils;
import lombok.extern.slf4j.Slf4j;
import org.bytesoft.compensable.Compensable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * Created by Ferry Chen on 2019/11/19.
 */
@Slf4j
@Compensable(interfaceClass = IOrderTccService.class, cancellableKey = "orderTccServiceCancel")
@Service("orderTccService")
public class OrderTccServiceImpl implements IOrderTccService {

    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private IProductsService productsService;
    @Autowired
    private IOrderMapper orderMapper;
    @Autowired
    private StroageFeignClient stroageFeignClient;
    @Autowired
    private PayTccFeignClient payTccFeignClient;
    @Autowired
    private StroageTccFeignClient stroageTccFeignClient;
    @Autowired
    private PayFeignClient payFeignClient;


    @Transactional(noRollbackFor = BaseException.class)
    @Override
    public int saveOrder(String orderId, String userId, List<Product> productsList) {
        Order order = orderMapper.selectById(orderId);
        log.info("comfire...");
        Order o = new Order();
        List<OrderDetail> details = new ArrayList<>();
        OrderDetail detail = null;
        int count = 0;
        double money = 0;
        //检查库存
        List<Product> sproduct = new ArrayList<>();
        boolean proFlag = false;
        for (Product product : productsList) {
            Products products = productsService.getById(product.getProductId());
            if (products != null) {
                Result pr = stroageFeignClient.getByProductId(products.getId());
                if (Result.check(pr)) {
                    throw new BaseException(pr.getErrmsg());
                }
                Stroage stroage = (Stroage) pr.getData();
                if (stroage.getCount() < product.getCount()) {
                    proFlag = true;
                }
                double total = DigitalUtils.multiply(products.getPrice(), product.getCount());
                money = DigitalUtils.add(money, total);
                detail = new OrderDetail();
                detail.setOrderId(orderId);
                detail.setProductId(products.getId());
                detail.setCount(product.getCount());
                detail.setPrice(products.getPrice());
                detail.setTotalPrice(total);
                detail.setInsertTime(new Date());
                detail.setUpdateTime(new Date());
                orderDetailMapper.insert(detail);
                count += product.getCount();
                detail = null;
            } else {
                proFlag = true;
            }
        }
        o.setId(orderId);
        o.setUserId(userId);
        o.setCount(count);
        o.setMoney(money);
        o.setInsertTime(new Date());
        o.setUpdateTime(new Date());
        o.setStatus(proFlag ? "-1" : "1");
        orderMapper.insert(o);
        if (proFlag) {
            throw new UnderstockException();
        }
        Result pr = payFeignClient.checkBalance(userId, money);
        if (Result.check(pr)) {
            Order update = new Order();
            update.setId(orderId);
            update.setStatus("-2");
            orderMapper.updateOrder(update);
            throw new NSFException();
        }
        for (Product product : productsList) {
            stroageTccFeignClient.consume(product.getProductId(), product.getCount());
        }
        Result re= payTccFeignClient.consume(userId, money);
        return 1;
    }
}
